import React, { useCallback, useEffect, useState } from 'react'
import pageLayout from '../common/PageLayout'
import { Button, Form, Input, Row, Col, message, Select, Checkbox, DatePicker } from 'antd'
import { UploadOutlined } from '@ant-design/icons'
import { deptListApi, fileUploadApi, roleListApi, saveUserApi, updatePwdApi, userInfoApi } from '../../apis/userApi'
import moment from 'moment'

const USER_OBJ = {
    id:'', 
    name: '', 
    password: '', 
    photo: '', 
    sex: '', 
    address: '', 
    birthday: '', 
    dept: '', 
    duties: '', 
    phone: '', 
    email: '', 
    role: [], 
    remark: ''
}

function Edit({history, location, match}) {

    const phoneRule = [
        { required: true, message: '请输入电话号码' },
        {validator: ((_, value) => {
            if (/^1[3-9]{1}[0-9]{9}$/.test(value)) {
                return Promise.resolve()
            } else {
                return Promise.reject(new Error('用户手机号输入错误'))
            }
        })}
    ],
    [roleList, setRoleList] = useState([]),
    [dept, setDept] = useState([]),
    [duties,setDuties] = useState([]),
    [user, setUser] = useState(JSON.parse(JSON.stringify(USER_OBJ))),
    [formNode] = Form.useForm(),
    //是否为修改页面的标识
    [isEdit, setIsEdit] = useState(false)

    //使用类似于类组件的生命周期 -- useEffect钩子函数中的回调方法，不要使用async + await
    useEffect(function() {

        console.log('---------------edit 修改数据');
        console.log(location,match);
        // 取到路由里边传递的参数，然后调用用户信息的接口，获取用户的信息然后进行赋值
        let id = location.state?.id // 新语法
        // let id = !!location.state ? location.state.id : undefined
        // 判断路由组件是否传递数据id过来
        if (!!id) {
            setIsEdit(true)
            userInfoApi(id).then(data => {
                console.log(data);
                let obj = {},
                    _data = data.data
                for (let name in USER_OBJ) {
                    // console.log(_data[name]);
                    obj[name] = _data[name] || ''
                }
                // console.log(obj);
                setUser(obj)
                formNode.setFieldsValue({
                    ...obj,
                    birthday: moment(!!obj.birthday ? new Date(obj.birthday) : new Date())
                })
            })
        }
        console.log('---------------edit 修改数据');

        roleListApi() .then(data => {
            // debugger
            // console.log(data);
            if (data.code === 200) {
                // setRoleList(data.data.rows.map(it => {
                //     it.label = it.name
                //     it.value = it.id
                //     return it
                // }))
                setRoleList(data.data.rows)
            }
            // console.log(roleList);
        })

        deptListApi().then(data => {
            if (data.code === 200) {
                // console.log(data);
                setDept(data.data)
            }
        })
    },[])

    //要用use Callback来进行函数定义优化
    const pickFileEve = useCallback(function() {
        //定义一个input输入框
        let input = document.createElement('input')
        // 定义input类型为file，使其为一个文件选择器
        input.setAttribute('type', 'file')
        // 监听input框事件
        input.onchange = function() {
            // 此处this指向事件源input
            // console.log(this);
            // debugger
            let file = this.files[0]
            // 判断数据类型是否为"image/"类型开头
            if (file.type.startsWith("image/")) {
                // 使用FormData来序列化file对象
                let formData = new FormData()

                // 给formData添加数据
                // FormData.append(name: string, value: string | Blob
                // 第一个为提交数据的字段名字，第二个为需要提交的数据
                formData.append('fileName',file)

                let cb = progress => {
                    console.log('文件已上传：' + (progress.loaded/progress.total * 100).toFixed(2) + '%.');
                }

                fileUploadApi(formData, cb).then(data => {
                    // debugger
                    // console.log(data);
                    if (data.code === 200) {
                        // 因为在表单数据中，如果需要各一个表单输入框赋值，还需要给Form.Item标点组件赋值才行
                        // 数据值就这样赋值， 页面表单展示值，需要使用表单方法来进行赋值
                        setUser({...user, photo: data.data[0].path})

                        // 给头像输入框的表单元赋值,使用setFieldsValue这个api方法来实现
                        formNode.setFieldsValue({photo: data.data[0].path})
                    } else {
                        message.error('用户上传头像失败')
                    }
                })
            } else {
                message.warn('用户头像必须选择图片')
            }
        }
        input.click()
    },[user])

    const saveEvt = useCallback(function() {
        // console.log(user,'1');
        //使用表单的单独校验方法来进行数据校验
        formNode.validateFields()
            .then(async function(){
                let result
                if (isEdit) {
                    // 用户编辑的时候，不能传递password参数
                    let obj = {}
                    for (let name in user) {
                        if (name !== 'password') obj[name] = user[name]
                    }
                    console.log(obj);
                    result = await updatePwdApi(obj)
                } else {
                    result = await saveUserApi(user)
                }
                console.log(result);
                if (result.code === 200) {
                    message.success(`${isEdit ? '修改' : '新增'}用户成功`)

                    // 对表单进行重置操作
                    formNode.resetFields()
                    // 清空数据
                    // console.log(user,'2');
                    setUser(JSON.parse(JSON.stringify(USER_OBJ)))

                    // 因为已经重置，因此需要把页面的编辑状态改为新增状态
                    setIsEdit(false)
                } else {
                    message.error(`用户${isEdit ? '修改' : '新增'}失败-原因:${result.message}`)
                }
            })
            .catch(()=>{})

        // console.log(user,'3');
    },[user, isEdit])

    return (
        <div className='my-layout-container'>
            <header>
                <Button type='primary' onClick={saveEvt}>保存</Button>
                <Button type='primary' ghost onClick={function() {history.push('/user/list')}}>返回</Button>
            </header>
            <article>
                {/* 必须使用form钩子函数来进行form属性绑定 */}
            <Form form={formNode} labelCol={{ style: {width:'86px'} }}>
                <Row gutter={16}>
                    <Col span={6}>
                        <Form.Item
                            label="用户编码"
                            name="id"
                            rules={[{ required: true, message: '请输入用户编码' }]}>
                            <Input value={user.id} onChange={
                                function(evl) {
                                    setUser({...user, id: evl.target.value})
                                }
                            } />
                        </Form.Item>
                    </Col>
                    <Col span={6}>
                        <Form.Item
                            label="用户姓名"
                            name="name"
                            rules={[{ required: true, message: '请输入用户姓名' }]}>
                            <Input value={user.name} onChange={
                                function(evl) {
                                    setUser({...user, name: evl.target.value})
                                }
                            } />
                        </Form.Item>
                    </Col>
                    {
                        !isEdit && <Col span={6}>
                        <Form.Item
                            label="用户密码"
                            name="password"
                            rules={[{ required: true, message: '请输入用户密码' }]}>
                            <Input value={user.password} onChange={
                                function(evl) {
                                    setUser({...user, password: evl.target.value})
                                }
                            } />
                        </Form.Item>
                    </Col>
                    }
                    <Col span={6}>
                        <Form.Item
                            label="用户头像"
                            name="photo">
                            <Input value={user.photo} readOnly placeholder='选择图片' addonAfter={<UploadOutlined onClick={pickFileEve}/>} />
                        </Form.Item>
                    </Col>
                    <Col span={6}>
                        <Form.Item
                            label="用户性别"
                            name="sex">
                            <Select value={user.sex} onChange={
                                val => {
                                    setUser({...user, sex: val})
                                }
                            }>
                                <Select.Option value="男">男</Select.Option>
                                <Select.Option value="女">女</Select.Option>
                                <Select.Option value="未知">未知</Select.Option>
                            </Select>
                        </Form.Item>
                    </Col>
                    <Col span={6}>
                        <Form.Item
                            label="用户生日"
                            name="birthday">
                            <DatePicker onChange={function(data) {
                                console.log(moment(data).format('yyyy-MM-DD'));
                                setUser({...user, birthday: moment(data).format('yyyy年MM月DD日')})
                            }} />
                        </Form.Item>
                    </Col>
                    <Col span={6}>
                        <Form.Item
                            label="用户部门"
                            name="dept">
                            <Select value={user.dept} onChange={function(val) {
                                // console.log(Evt);
                                let _dept = dept.find(it => it.name === val)
                                setDuties(!!_dept ? _dept.children : [])
                                setUser({...user, dept: val})
                            }}>
                                {
                                    dept.map(it => {
                                        return <Select.Option key={it.name} value={it.name}>{it.name}</Select.Option>
                                    })
                                }
                            </Select>
                        </Form.Item>
                    </Col>
                    <Col span={6}>
                        <Form.Item
                            label="用户职位"
                            name="duties">
                            <Select value={user.duties} onChange={
                                val => {
                                    setUser({...user, duties: val})
                                }
                            }>
                                {
                                    duties.map(it => {
                                        return <Select.Option key={it} value={it}>{it}</Select.Option>
                                    })
                                }
                            </Select>
                        </Form.Item>
                    </Col>
                    <Col span={6}>
                        <Form.Item
                            label="电话号码"
                            name="phone"
                            rules={phoneRule}>
                            <Input value={user.photo} onChange={
                                evt => {
                                    setUser({...user, phone: evt.target.value})
                                }
                            } placeholder="请输入电话号码"/>
                        </Form.Item>
                    </Col>
                    <Col span={6}> 
                        <Form.Item
                            label="电子邮箱"
                            name="email">
                            <Input value={user.email} onChange={
                                evt => {
                                    setUser({...user, email: evt.target.value})
                                }
                            } placeholder="请输入电子邮箱"/>
                        </Form.Item>
                    </Col>
                    <Col span={20}>
                        <Form.Item
                            label="用户权限"
                            name="role">
                            <Checkbox.Group 
                            style={{ width: '100%' }}
                            value={user.role}
                            onChange={function(val) {
                                // console.log(arguments,q);
                                setUser({...user, role: val})
                            }} >
                            <Row gutter={1}>
                                {
                                    roleList.map(it => {
                                        return (<Col key={it.id}>
                                            <Checkbox value={it.id}>{it.name}</Checkbox>
                                        </Col>)
                                    })
                                }
                            </Row>
                        </Checkbox.Group>
                        </Form.Item>
                    </Col>
                    <Col span={24}>
                        <Form.Item
                            label="用户地址"
                            name="address">
                            <Input value={user.address} onChange={
                                evt => {
                                    setUser({...user, address: evt.target.value})
                                }
                            } placeholder="请输入用户地址"/>
                        </Form.Item>
                    </Col>
                    <Col span={24}>
                        <Form.Item
                            label="备注"
                            name="remark">
                            <Input value={user.mark} onChange={
                                evt => {
                                    setUser({...user, remark: evt.target.value})
                                }
                            } placeholder="请输入备注"/>
                        </Form.Item>
                    </Col>
                </Row>
            </Form>
            </article>
        </div>
    )
}

export default pageLayout(Edit)